/**
 * 定义：将一个复杂对象的构建与其表示相分离，使得同样的构建过程可以创建不同的表示。
 * a)Builder 模式主要用于“分步骤构建一个复杂的对象”。在这其中“分步骤”是一个稳定的算法，而复杂对象的各个部分则经常变化。
    b)变化点在哪里，封装哪里 —— Builder模式主要在于应对“复杂对象各个部分”的频繁需求变动。其缺点在于难以应对“分步骤构建算法”的需求变动。
    c)Abstract Factory模式解决“系列对象”的需求变化，Builder模式解决“对象部分”的需求变化。Builder模式通常和Composite模式组合使用。
 */
// class Builder {
//   constructor() {
//     this.house = {
//       doors: [],
//       walls: []
//     }
//   }
//   buildDoor() {
//     throw new Exception("抽象方法不能直接调用")
//   }
//   buildWall() {
//     throw new Exception("抽象方法不能直接调用")
//   }
//   getHouse() {
//     return this.house
//   }
// }

// class ChineseBuilder extends Builder {
//   buildDoor() {
//     this.house.doors.push("中式门")
//   }
//   buildWall() {
//     this.house.walls.push("中式墙")
//   }
// }

// class EnglishBuilder extends Builder {
//   buildDoor() {
//     this.house.doors.push("英式门")
//   }
//   buildWall() {
//     this.house.walls.push("英式墙")
//   }
// }

// class BuilderManager {
//   constructor(builder) {
//     this.builder = builder
//     // console.log(builder)
//   }


//   createHouse() {
//     this.builder.buildDoor();
//     this.builder.buildWall();
//     return this.builder.getHouse();
//   }
// }
// const CONFIG = {
//   builderClass: EnglishBuilder
// }
// const builder = new BuilderManager(Reflect.construct(CONFIG.builderClass, []))
// const house = builder.createHouse()
// console.log(house)

const CONFIG = {
  builderName: 'chinese'
}

const builder = {
  baseBuilder: {
    house: {
      doors: [],
      walls: []
    },
    getHouse() {
      return this.house
    }
  }
}
builder.chineseBuilder = Object.create(builder.baseBuilder, {
  buildDoor: { 
    value: function() {
      this.house.doors.push("中式门")
    }
  },
  buildWall: {
    value: function() {
      this.house.walls.push("中式墙")
    }
  },
})

builder.englishBuilder = Object.create(builder.baseBuilder, {
  buildDoor: {
    value: function() {
      this.house.doors.push("英式门")
    }
  },
  buildWall: {
    value: function() {
      this.house.walls.push("英式墙")
    }
  },
})

const builderManager = {
  builder: builder[`${CONFIG.builderName}Builder`],
  createHouse: function() {
    // console.log(this.builder)
    this.builder.buildDoor();
    // this.builder.buildDoor();
    // this.builder.buildWall();
    this.builder.buildWall();
    return this.builder.getHouse();
  },
}
const house = builderManager.createHouse()
console.log(house)
